package com.boss.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boss.api.dto.ApiResultDTO;
import com.boss.common.entity.TaskDTO;
import com.boss.common.entity.WfActionDTO;
import com.boss.common.enums.ActionTypeEnum;
import com.boss.common.service.IWorkflowBusiness;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.sys.config.CseCommonConfiguration;
import com.boss.sys.utils.JsonUtil;
import com.boss.sys.utils.SysUtils;
import com.boss.sys.workflow.dto.OperationLogDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class WorkflowBusinessImpl implements IWorkflowBusiness {

    public static final String SUCCESS_CODE = "100000";
    public static final String RSCODE = "rscode";
    /**
     * 引入模板配置类
     */
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 引入配置类
     */
    @Autowired
    private CseCommonConfiguration commonConfiguration;
    /**
     * 引入日志框架
     */
    private final static Logger logger = LoggerFactory.getLogger(WorkflowBusinessImpl.class);

    @Override
    public ApiResultDTO doWorkFlowList(UserDTO user, WfActionDTO wfActionDTO,String tokenid) throws AppRuntimeException {
        ActionTypeEnum actionType = ActionTypeEnum.toEnum(wfActionDTO.getActionType());
        logger.info("datas:" + wfActionDTO.getBizDatas() + "，processDefKey:" + wfActionDTO.getProcessDefKey() +
                "，menuguid=" + wfActionDTO.getMenuguid() + "，action" + actionType.getActionTypeCode() +
                "，actionName：" + actionType.getActionTypeName());
        if (SysUtils.isNullOrEmpty(wfActionDTO.getBizDatas())) {
            throw new AppRuntimeException("流程数据不能为空");
        }
//        List<Object> lists = new ArrayList<>();
//        lists.add(wfActionDTO.getBizDatas());
        //构造请求参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("processDefKey", wfActionDTO.getProcessDefKey());
        params.add("menuguid", wfActionDTO.getMenuguid());
        params.add("actionType", actionType.getActionTypeCode());
        params.add("actionName", wfActionDTO.getActionName());
        params.add("year", wfActionDTO.getYear());
        params.add("province", wfActionDTO.getProvince());
        params.add("bizDatas", JSON.toJSONString(wfActionDTO.getBizDatas()));
        params.add("bizKeyName", wfActionDTO.getBizKeyName());
        params.add("message", wfActionDTO.getMessage());
        params.add("backMenuguid", wfActionDTO.getBackMenuguid());
        params.add("userId", wfActionDTO.getUserId());
        params.add("tokenid",tokenid);
        logger.info("params : " + params);
        //构造实体对象
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/actions";
        String str = restTemplate.postForObject(url, params, String.class);
        JSONObject jsonObject = JSON.parseObject(str);
        logger.info(jsonObject.toString());

        if(SUCCESS_CODE.equals(jsonObject.get(RSCODE))){
            return ApiResultDTO.success(jsonObject.get("data"), (String)jsonObject.get("result"));
        }else{
            throw new AppRuntimeException((String)jsonObject.get("result"));
        }
    }

    @Override
    public ApiResultDTO doWorkFlow(UserDTO user, WfActionDTO wfActionDTO,String tokenid) throws AppRuntimeException {
        ActionTypeEnum actionType = ActionTypeEnum.toEnum(wfActionDTO.getActionType());
        logger.info("datas:" + wfActionDTO.getBizDatas() + "，processDefKey:" + wfActionDTO.getProcessDefKey() +
                "，menuguid=" + wfActionDTO.getMenuguid() + "，action" + actionType.getActionTypeCode() +
                "，actionName：" + actionType.getActionTypeName());
        if (SysUtils.isNullOrEmpty(wfActionDTO.getBizDatas())) {
            throw new AppRuntimeException("流程数据不能为空");
        }
        List<Object> lists = new ArrayList<>();
        lists.add(wfActionDTO.getBizDatas());
        //构造请求参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("processDefKey", wfActionDTO.getProcessDefKey());
        params.add("menuguid", wfActionDTO.getMenuguid());
        params.add("actionType", actionType.getActionTypeCode());
        params.add("actionName", wfActionDTO.getActionName());
        params.add("year", wfActionDTO.getYear());
        params.add("province", wfActionDTO.getProvince());
        params.add("bizDatas", JSON.toJSONString(lists));
        params.add("bizKeyName", wfActionDTO.getBizKeyName());
        params.add("backMenuguid", wfActionDTO.getBackMenuguid());
        params.add("message", wfActionDTO.getMessage());
        params.add("userId", wfActionDTO.getUserId());
        params.add("tokenid", tokenid);
        logger.info("params : " + params);
        //构造实体对象
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/actions";
        String str = restTemplate.postForObject(url, params, String.class);
        JSONObject jsonObject = JSON.parseObject(str);
        logger.info(jsonObject.toString());

        if(SUCCESS_CODE.equals(jsonObject.get(RSCODE))){
            return ApiResultDTO.success(jsonObject.get("data"), (String)jsonObject.get("result"));
        }else{
            throw new AppRuntimeException((String)jsonObject.get("result"));
        }
//        return ApiResultDTO.success("", "操作成功");
    }

    @Override
    public List<Map> queryWorkFlowStatus(UserDTO user, WfActionDTO wfActionDTO,List<String> statuses,List<String> bizkeyList,String tokenid) throws AppRuntimeException {

        //构造请求参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("processDefKey", wfActionDTO.getProcessDefKey());
        params.add("menuguid", wfActionDTO.getMenuguid());
        params.add("statuses", JSON.toJSONString(statuses));
        params.add("year", user.getYear());
        params.add("province", user.getProvince());
        params.add("bizKeys", JSON.toJSONString(bizkeyList));
        params.add("tokenid",tokenid);
        logger.info("params : " + params);
        //构造实体对象
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/bizkeys/status";
        String str = restTemplate.postForObject(url, params, String.class);
        JSONObject jsonObject = JSON.parseObject(str);
        logger.info(jsonObject.toString());
        if(SUCCESS_CODE.equals(jsonObject.get(RSCODE))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            List<Map> maps = jsonArray.toJavaList(Map.class);
            return maps;
        }else{
            throw new AppRuntimeException((String)jsonObject.get("result"));
        }
//        List<Map> maps = new ArrayList<>();
//        return maps;
    }

    @Override
    public List<String> queryWorkflowInfo(UserDTO userDTO, WfActionDTO wfActionDTO,String tokenid) throws AppRuntimeException {
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/bizkeys/instate?processDefKey=" +
                wfActionDTO.getProcessDefKey() + "&menuguid=" + wfActionDTO.getMenuguid() + "&status=" +
                wfActionDTO.getStatus() + "&province=" + userDTO.getProvince() + "&year=" + userDTO.getYear()+"&tokenid="+tokenid;
        logger.info("获取流程信息{}",url);
        String str = restTemplate.getForObject(url, String.class);
        List<String> idList = null;
        JSONObject jsonObject = JSON.parseObject(str);
        if (SUCCESS_CODE.equals(jsonObject.get(RSCODE))) {
            Object data = jsonObject.get("data");
            if (!SysUtils.isNullOrEmpty(data)) {
                idList = JSON.parseArray(JSON.toJSONString(data), String.class);
            }
        } else {
            throw new AppRuntimeException((String) jsonObject.get("result"));
        }
//        List<String> idList =new ArrayList<>();
//        idList.add("256368CB12804EA4A45E0C41921F1ADA");
        return idList;
    }

    @Override
    public List<OperationLogDTO> getOperationLogDTOS(String id, String province, Integer year) throws AppRuntimeException {
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/actionlogs?processDefKey=bas_asset_manager&bizKey="
                + id + "&province=" + province + "&year=" + year;
        String strObject = restTemplate.getForObject(url, String.class, new Object());
        List<OperationLogDTO> list = null;
        JSONObject jsonObject = JSON.parseObject(strObject);
        if ("100000".equals(jsonObject.get("rscode"))) {
            Object data = jsonObject.get("data");
            if (!SysUtils.isNullOrEmpty(data)) {
                list = JSON.parseArray(JSON.toJSONString(data), OperationLogDTO.class);
            }
        } else {
            throw new AppRuntimeException((String) jsonObject.get("result"));
        }
        return list;
    }

    @Override
    public List<TaskDTO> getToDoTask(Map<String, Object> config, String menuguid, String province, String year) throws AppRuntimeException {
        try {
            String url = commonConfiguration.getBpmnx() + "/v2/workflow/counts?processDefKey=" + config.get("processid") + "&menuguids="
                    + menuguid + "&statuses=1,4&province=" + province + "&year=" + year;
            String reponse = restTemplate.getForObject(url, String.class);
            Map<String, Object> result = JsonUtil.jsonToHashMap(reponse);
            if (ApiResultDTO.RSCODE_SUCCESS.equals(SysUtils.nonNullStr(result.get("rscode")))) {
                return JsonUtil.jsonToList(JsonUtil.listToJson((List) result.get("data")), TaskDTO.class);
            } else {
                throw new AppRuntimeException("错误码：{" + result.get("rscode") + "}， 错误返回值:{" + result.get("result") + "}");
            }
        } catch (Exception e) {
            throw new AppRuntimeException("远程查询业务系统代办失败" + e.getMessage());
        }
    }

    @Override
    public List<Map> getAuditInstruction(WfActionDTO wfActionDTO,String tokenid) {
        List<Map> list =new ArrayList<>();

        try {
            String url = commonConfiguration.getBpmnx()+ "/v2/workflow/actionlogs?processDefKey=" + wfActionDTO.getProcessDefKey() + "&bizKey="
                    + wfActionDTO.getBusinessKeys()+ "&tokenid=" + tokenid+ "&year=" +wfActionDTO.getYear() + "&province=" + wfActionDTO.getProvince();

            String response = restTemplate.getForObject(url, String.class);
            JSONObject json=JSONObject.parseObject(response);
            if(!StringUtils.isEmpty(json.getJSONArray("data"))){
                JSONArray jsonArray = json.getJSONArray("data");
                List<Map> maps = jsonArray.toJavaList(Map.class);
                return maps;
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        }
         return list;
    }

    @Override
    public ApiResultDTO terminations(UserDTO user, WfActionDTO wfActionDTO) throws AppRuntimeException {
        logger.info("作废流程datas:" + wfActionDTO.getBizDatas() + "，processDefKey:" + wfActionDTO.getProcessDefKey());
        if (SysUtils.isNullOrEmpty(wfActionDTO.getBizDatas())) {
            throw new AppRuntimeException("流程数据不能为空");
        }

        //构造请求参数
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("processDefKey", wfActionDTO.getProcessDefKey());
        params.add("year", wfActionDTO.getYear());
        params.add("province", wfActionDTO.getProvince());
        params.add("bizKeys", wfActionDTO.getBizDatas());
        params.add("userId", wfActionDTO.getUserId());
        logger.info("params : " + params);
        //构造实体对象
        String url = commonConfiguration.getBpmnx() + "/v2/workflow/action/terminations";
        String str = restTemplate.postForObject(url, params, String.class);
        JSONObject jsonObject = JSON.parseObject(str);
        logger.info(jsonObject.toString());

        if(SUCCESS_CODE.equals(jsonObject.get(RSCODE))){
            return ApiResultDTO.success(jsonObject.get("data"), (String)jsonObject.get("result"));
        }else{
            throw new AppRuntimeException((String)jsonObject.get("result"));
        }
    }

}
